package cn.yj.common.monitor;

import cn.yj.alipay.emums.AlipayOrderStatus;
import cn.yj.common.emums.PayType;
import cn.yj.common.entity.PayOrder;
import cn.yj.common.entity.PayRefundOrder;
import cn.yj.common.entity.RefundQueryParams;
import cn.yj.common.interfaces.AbstractPay;
import cn.yj.commons.utils.StringUtils;

import java.util.concurrent.TimeUnit;

/**
 * @author 永健
 * @since 2022-02-21 10:06
 */
public class AlipayOrderMonitor extends AbstractPayOrderMonitor {


    /**
     * 注意：要生成退款订单后才可以
     *
     * @param expireTime  订单过期为支付时间
     * @param params      参数
     * @param abstractPay 发起退监控方
     */
    @Override
    public void refundMonitor(RefundQueryParams params, AbstractPay abstractPay) {
        PayRefundOrder payRefundOrder = abstractPay.queryRefundOrder(params);
        if (payRefundOrder.isSuccess()) {
            notifyRefundHandler.syncNotify(PayType.WECHAT, true, params.getOutTradeNo());
            return;
        }
        this.loopOrderPayRefundStatus(params, 10, 10, abstractPay);
    }

    /**
     * 注：需要在支付平台生成订单后调用
     *
     * @param outTradeNo 商户订单号
     */
    @Override
    public void payMonitor(long expireTime, String outTradeNo, AbstractPay abstractPay) {
        PayOrder payOrder = abstractPay.queryOrder(outTradeNo);
        this.loopOrderPayStatus(expireTime, payOrder, 10, abstractPay);
    }


    /**
     * 递归 count 次数去查询退款结果
     *
     * @param params 订单
     * @param delay  延迟多长时间执行单位秒
     */
    private void loopOrderPayRefundStatus(
            RefundQueryParams params, long delay, int count, AbstractPay abstractPay) {
        if (count < 0) {
            return;
        }
        --count;
        int finnalCount = count;
        scheduledExecutorService.schedule(() -> {
            PayRefundOrder payOrder;
            try {
                payOrder = abstractPay.queryRefundOrder(params);
                if (payOrder.isSuccess()) {
                    notifyRefundHandler.syncNotify(PayType.ALIPAY, true, params.getOutTradeNo());
                    return;
                }
                if (!payOrder.isSuccess()) {
                    this.loopOrderPayRefundStatus(params, delay, finnalCount, abstractPay);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, delay, TimeUnit.SECONDS);
    }


    private void loopOrderPayStatus(long expireTime, PayOrder order, long delay, AbstractPay abstractPay) {
        if (expireTime < System.currentTimeMillis()) {
            return;
        }
        scheduledExecutorService.schedule(() -> {
            PayOrder payOrder;
            try {
                payOrder = abstractPay.queryOrder(order.getOutTradeNo());
                // 交易成功就通知
                if (payOrder.isSuccess()) {
                    notifyHandler.syncNotify(PayType.ALIPAY, order.getOutTradeNo());
                    return;
                }
                // 失败后 继续延迟执行查询
                if (!payOrder.isSuccess()) {
                    if (AlipayOrderStatus.WAIT_BUYER_PAY.name().equals(payOrder.getTradeStatus()) || StringUtils.isBlank(payOrder.getTradeStatus())) {
                        this.loopOrderPayStatus(expireTime, payOrder, delay, abstractPay);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, delay, TimeUnit.SECONDS);
    }


}
